import java.util.Enumeration;
import java.util.Vector;

/**
 * @author eli.hou
 * 顾客
 */
public class Customer {

    private String name;
    private Vector<Rental> rentals = new Vector<>();

    public Customer(String name) {
        this.name = name;
    }

    public void addRental(Rental ary){
        rentals.addElement(ary);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    //region 原始方法
    /**
     * 生成详单
     * 重构：
     *      1.代码块太长了，导致代码的职责太多了
     *      2.switch 逻辑泥团需要独立为函数
     *
     */
    public String statement(){
        double totalAmount = 0;
        int frequentRenterPoints = 0;
        Enumeration _rentals = rentals.elements();
        String result = "Rental Record for " + getName() + "\n";
        while (_rentals.hasMoreElements()){
            double thisAmount = 0;
            Rental each = (Rental) _rentals.nextElement();

            //determine amounts for each line
            switch (each.getMovie().getPriveCode()){
                case  Movie.REGULAR:
                    thisAmount += 2;
                    if(each.getDaysRented() > 2)
                        thisAmount += (each.getDaysRented() - 2) * 1.5;
                    break;
                case Movie.NEW_RELEASE:
                    thisAmount += each.getDaysRented() * 3;
                    break;
                case Movie.CHILDRENS:
                    thisAmount += 1.5;
                    if (each.getDaysRented() > 3)
                        thisAmount += (each.getDaysRented() - 3) * 1.5;
                    break;
            }

            // add frequent renter points
            frequentRenterPoints ++;
            // add bonus for a two day new release rental
            if ((each.getMovie().getPriveCode() == Movie.NEW_RELEASE) &&
                each.getDaysRented() > 1 ) frequentRenterPoints ++;

            // show figures for this rental
            result += "\t" + each.getMovie().getTitle() + "\t" +
                    String.valueOf(thisAmount) + "\n";
            thisAmount += totalAmount;
        }
        //add footer lines
        result += "Amount owed is " + String.valueOf(totalAmount) + "\n";
        result += "You earned " + String.valueOf(frequentRenterPoints) +
                " frequent renter points";
        return result;
    }
    //endregion

    //region 重构方法(switch 泥团代码块分离出去)

    public String statement01(){
        double totalAmount = 0;
        int frequentRenterPoints = 0;
        Enumeration _rentals = rentals.elements();
        String result = "Rental Record for " + getName() + "\n";
        while (_rentals.hasMoreElements()){
            double thisAmount = 0;
            Rental each = (Rental) _rentals.nextElement();

            // thisAmount = amountFor(each);
            // 此处代码就修改为each的getCharge()
            thisAmount = each.getCharge();

            // add frequent renter points
            frequentRenterPoints ++;
            // add bonus for a two day new release rental
            if ((each.getMovie().getPriveCode() == Movie.NEW_RELEASE) &&
                    each.getDaysRented() > 1 ) frequentRenterPoints ++;

            // show figures for this rental
            result += "\t" + each.getMovie().getTitle() + "\t" +
                    String.valueOf(thisAmount) + "\n";
            thisAmount += totalAmount;
        }
        //add footer lines
        result += "Amount owed is " + String.valueOf(totalAmount) + "\n";
        result += "You earned " + String.valueOf(frequentRenterPoints) +
                " frequent renter points";
        return result;
    }

//    private double amountFor(Rental each) {
//        double thisAmount = 0;
//        //determine amounts for each line
//        switch (each.getMovie().getPriveCode()){
//            case  Movie.REGULAR:
//                thisAmount += 2;
//                if(each.getDaysRented() > 2)
//                    thisAmount += (each.getDaysRented() - 2) * 1.5;
//                break;
//            case Movie.NEW_RELEASE:
//                thisAmount += each.getDaysRented() * 3;
//                break;
//            case Movie.CHILDRENS:
//                thisAmount += 1.5;
//                if (each.getDaysRented() > 3)
//                    thisAmount += (each.getDaysRented() - 3) * 1.5;
//                break;
//        }
//        return thisAmount;
//    }

    //修改amountFor方法内的变量名
    //思考：这样修改变量名称是值得的行为吗？
    //绝对值得，好的代码应该清除表达自己的功能，变量名是代码清晰的关键。

    //思考：amountFor() 使用了Rental类的信息，却没有使用来自Customer类的信息，amountFor() 是否适合放在此处？
    //把该方法移至Rental类

//    private double amountFor01(Rental aRental) {
//        double result = 0;
//        //determine amounts for each line
//        switch (aRental.getMovie().getPriveCode()){
//            case  Movie.REGULAR:
//                result += 2;
//                if(aRental.getDaysRented() > 2)
//                    result += (aRental.getDaysRented() - 2) * 1.5;
//                break;
//            case Movie.NEW_RELEASE:
//                result += aRental.getDaysRented() * 3;
//                break;
//            case Movie.CHILDRENS:
//                result += 1.5;
//                if (aRental.getDaysRented() > 3)
//                    result += (aRental.getDaysRented() - 3) * 1.5;
//                break;
//        }
//        return result;
//    }

    //endregion



    //region 新思考：thisAmount 变得有点多余，它接受each.getCharge()的执行结果之后就不回再有任何改变了

    //尽量去除掉临时变量，然后each.getCharge()方法就会被执行两次，然后再对each.getCharge()方法进行优化

    //思考："常客积分计算"做类似处理。积分的计算可能会发生变化，把积分运算的职责交给Rental类 改变结果statement03()方法

    public String statement02(){
        double totalAmount = 0;
        int frequentRenterPoints = 0;
        Enumeration _rentals = rentals.elements();
        String result = "Rental Record for " + getName() + "\n";
        while (_rentals.hasMoreElements()){
            Rental each = (Rental) _rentals.nextElement();

            frequentRenterPoints ++;
            // add bonus for a two day new release rental
            if ((each.getMovie().getPriveCode() == Movie.NEW_RELEASE) &&
                    each.getDaysRented() > 1 ) frequentRenterPoints ++;

            // show figures for this rental
            result += "\t" + each.getMovie().getTitle() + "\t" +
                    each.getCharge() + "\n";
            totalAmount += each.getCharge();
        }
        //add footer lines
        result += "Amount owed is " + totalAmount + "\n";
        result += "You earned " + frequentRenterPoints +
                " frequent renter points";
        return result;
    }

    public String statement03(){
        double totalAmount = 0;
        int frequentRenterPoints = 0;
        Enumeration _rentals = rentals.elements();
        String result = "Rental Record for " + getName() + "\n";
        while (_rentals.hasMoreElements()){
            Rental each = (Rental) _rentals.nextElement();

            frequentRenterPoints += each.getFrequentRenterPoints();

            // show figures for this rental
            result += "\t" + each.getMovie().getTitle() + "\t" +
                    each.getCharge() + "\n";
            totalAmount += each.getCharge();
        }
        //add footer lines
        result += "Amount owed is " + totalAmount + "\n";
        result += "You earned " + frequentRenterPoints +
                " frequent renter points";
        return result;
    }
    //endregion


    //region 去除临时变量

    //利用查询函数来取代totalAmount、frequentRenterPoints这两个临时变量


    // totalAmount : Customer 类的getTotalCharge()来取代
    // frequentRenterPoints : Customer 类的getTotalFrequentRenterPoints()来取代

    private double getTotalCharge(){
        double result = 0;
        Enumeration _rentals = rentals.elements();
        while (_rentals.hasMoreElements()){
            Rental each = (Rental) _rentals.nextElement();
            result += each.getCharge();
        }
        return result;
    }

    private int getTotalFrequentRenterPoints(){
        int result = 0;
        Enumeration _rentals = rentals.elements();
        while (_rentals.hasMoreElements()){
            Rental each = (Rental) _rentals.nextElement();
            result += each.getFrequentRenterPoints();
        }
        return result;
    }



    public String statement04(){
        Enumeration _rentals = rentals.elements();
        String result = "Rental Record for " + getName() + "\n";
        while (_rentals.hasMoreElements()){
            Rental each = (Rental) _rentals.nextElement();

            // show figures for this rental
            result += "\t" + each.getMovie().getTitle() + "\t" +
                    each.getCharge() + "\n";
        }
        //add footer lines
        result += "Amount owed is " + getTotalCharge() + "\n";
        result += "You earned " + getTotalFrequentRenterPoints() +
                " frequent renter points";
        return result;
    }
    //endregion


}
